Qt中利用Qwt画动态正弦曲线,并可动态调整振幅和周期 您所在的位置:网站首页 qt绘制动态曲线 滚动条数据回放 Qt中利用Qwt画动态正弦曲线,并可动态调整振幅和周期

Qt中利用Qwt画动态正弦曲线,并可动态调整振幅和周期

2024-07-09 08:51| 来源: 网络整理| 查看: 265

前言:

这里主要是做出了一个动态的正弦曲线,并可以调整正弦曲线的振幅和周期。网上有很多画动态正弦曲线的,有一些是通过绘制一整个正弦图像,然后每一次显示都是刷新一整个正弦曲线来达到动态的效果,但是有时候需要的效果可能不是这样。

这里的正弦曲线主要是通过在数据容器中每次追加一个曲线点来达到动态的效果。当当前的坐标轴已经画满了曲线,那么就更新当前的坐标系,将当前坐标轴往前移动一个单位( x 轴 坐标 +1),这样整个坐标系就会看到往前移动了,显示出动态的效果。而动态地改变周期和振幅,则是通过按钮来改变,当点击一下对应的按钮时,就根据当前的振幅和周期,重新生成正弦曲线点,然后把改变前的数据擦除,重新追加新的数据进数据容器中,再重新绘图显示,这样就能改变图像的周期和振幅了。

下面是效果图:

这里写图片描述

一、准备好调整Sin曲线的接口

首先给出产生正弦曲线数据点的代码,这里的代码我在linux上用纯C写,把它编译成库,供Qt调用

/* SinData.h */ #ifndef SINDATA_H #define SINDATA_H #include #include #include #include void StartSin(); //启动线程 int GetSinData(int *AxisX,int *AxisY); //获取Sin坐标点 void SetAmplitude(int Amplitude); // 设置振幅 void SetCycle(int Cycle); // 设置周期 void SetSinOffset( int SinOffset); // 设置Y轴偏移量 void UpdateSinData(int AxisX[],int AxisY[]); // 更新Sin数据 #endif /* SinData.c */ #include "SinData.h" #define PI 3.1415926 #define BUFFER_SIZE 1024 int g_Buffer[BUFFER_SIZE]; int g_BufferIndex; int g_AxisX; int g_AxisY; int g_AxisIndex; int g_Amplitude = 25; int g_Cycle = 6; int g_SinOffset = 135; /* Function Name : SetAmplitude Description : 设置振幅 Input Parameters: Amplitude :振幅值 */ void SetAmplitude(int Amplitude) { g_Amplitude = Amplitude; } /* Function Name : SetCycle Description : 设置周期 Input Parameters: Cycle :周期 */ void SetCycle(int Cycle) { g_Cycle = Cycle; } /* Function Name : SetSinOffset Description : 设置偏移量 Input Parameters: SinOffset :y轴的偏移量 */ void SetSinOffset( int SinOffset) { g_SinOffset = SinOffset; } /* Function Name: RecvData Description : 设置完参数后,用来重新生成数据,更新Sin图像 */ void UpdateSinData(int AxisX[],int AxisY[]) { int m; for(m = 0; m move(10,5); m_FHRQwtPlot->setFixedWidth(780); // 设置坐标轴的大小 m_FHRQwtPlot->setFixedHeight(210); m_FHRQwtPlot->setTitle(" "); // 设置坐标轴的标题 m_FHRQwtPlot->setAxisScale(QwtPlot::yLeft,30,240,30); // 坐标轴的范围和间隔 m_FHRQwtPlot->setAxisScale(QwtPlot::yRight,30,240,30); m_FHRQwtPlot->setAxisScale(QwtPlot::xBottom,0,100,20); m_FHRQwtPlot->enableAxis(QwtPlot::yRight,true); m_FHRQwtPlot->enableAxis(QwtPlot::xBottom,false); // 隐藏X轴 m_FHRQwtPlot->setStyleSheet("background:transparent;");//删除坐标轴背景 m_FHRQwtPlot->setAxisMaxMinor(QwtPlot::xBottom,4); m_FHRQwtPlot->setAxisMaxMinor(QwtPlot::yLeft,3);//设置每一个大格有都少个小格 m_FHRQwtPlot->setAxisMaxMinor(QwtPlot::yRight,3); m_FHRQwtPlot->setAxisScaleDraw(QwtPlot::xBottom,new TimeScaleDraw( QDateTime::currentDateTime()));// 横坐标显示当前时间(需要把X轴显示出来,才能显示出时间) m_FHRQwtPlot->setCanvasBackground(Qt::white); // 设置背景白色 // 删除坐标轴间的间距 for ( int n = 0; n axisCnt; n++ ) { QwtScaleWidget *poScaleWidget = m_FHRQwtPlot->axisWidget( n); if (poScaleWidget) { poScaleWidget->setMargin( 0 ); } QwtScaleDraw *poScaleDraw = m_FHRQwtPlot->axisScaleDraw( n ); if ( poScaleDraw ) { poScaleDraw->enableComponent( QwtAbstractScaleDraw::Backbone, false ); } } m_FHRQwtPlot->plotLayout()->setAlignCanvasToScales( true ); //画网格 QwtPlotGrid *grid = new QwtPlotGrid(); grid->enableXMin(true); grid->enableYMin(true); grid->enableX(true); grid->enableY(true); grid->setMajorPen(QPen(Qt::gray,1,Qt::SolidLine)); // 大网格 grid->setMinorPen(QPen(QColor(186,186,186),0,Qt::DotLine));// 小网格 grid->attach(m_FHRQwtPlot); // 往坐标系添加曲线 m_FHRCurve = new QwtPlotCurve; m_FHRCurve->setPen(QColor(255,85,255),2,Qt::SolidLine); m_FHRCurve->setCurveAttribute(QwtPlotCurve::Fitted,true); //圆滑显示曲线 m_FHRCurve->setRenderHint(QwtPlotItem::RenderAntialiased,true); m_FHRCurve->attach(m_FHRQwtPlot); // 把曲线加载到坐标轴上 //m_UpdateFlag = 0; //m_LimitBackGroud = new Background(m_HighLimit,m_LowLimit);//给绘图填充背景 //m_LimitBackGroud->attach( m_FHRQwtPlot );//插入plot // 启动定时器 m_SinTimer = new QTimer(); connect(m_SinTimer,SIGNAL(timeout()),this,SLOT(TimeSlot())); StartSin(); // 开始启动线程,产生Sin坐标点(上面SinData.h里面的接口函数) m_SinTimer->start(500); } /************************************************************************** Function Name: TimeSlot Description: 定时器槽函数,用来绘制Sin图像 **************************************************************************/ void Widget::TimeSlot() { static int s_BeginAixsX = 0; // 起始横坐标 static int s_Result ; if ( (s_Result =GetSinData(&m_SinPointX,&m_SinPointY)) = 100) // 当当前坐标轴画满了,就把坐标轴往前移动,(更新X轴范围) { s_BeginAixsX++; m_FHRQwtPlot->setAxisScale(QwtPlot::xBottom,s_BeginAixsX,m_SinPointX,20);// 更新坐标轴 m_DataVectorX.erase(m_DataVectorX.begin(),m_DataVectorX.begin()+1); m_DataVectorY.erase(m_DataVectorY.begin(),m_DataVectorY.begin()+1); } m_DataVectorX.append((double)m_SinPointX); m_DataVectorY.append((double)m_SinPointY); m_FHRCurve->setSamples(m_DataVectorX,m_DataVectorY); // 绘图 m_FHRQwtPlot->replot(); // 重绘,一定要调用否则没效果 }

经过了上面的代码,此时Sin图像已经绘制成功了,并能显示出动态的效果,但是还没有调整振幅和周期。这个需要画两个QPushButton或者QToolButton,在点击信号对应的槽上来处理。当点击按钮时,Sin图像就会产生相应的变化。

//更改sin图像的Y轴偏移量、振幅、周期的槽函数。 void Widget::ChangeSinOffset() { m_UpdateFlag = DATA_UPDATA; static int s_SinOffset = 120; if(s_SinOffset == 160) s_SinOffset = 120; s_SinOffset +=10; SetSinOffset(s_SinOffset); UpdateData(); } void Widget::ChangeAmplitude() { static int s_SinAmplitude = 20; if(s_SinAmplitude == 50) s_SinAmplitude = 20; m_UpdateFlag = DATA_UPDATA; s_SinAmplitude += 5 ; SetAmplitude(s_SinAmplitude); UpdateData(); } void Widget::ChangeCycle() { static int s_SinCycle = 4; if(s_SinCycle == 10) s_SinCycle = 4; m_UpdateFlag = DATA_UPDATA; s_SinCycle +=1; SetCycle(s_SinCycle); UpdateData(); } /**************************************************************************/ //Function Name: updateData //Description: 更新sin图形的坐标,重绘 /**************************************************************************/ void Widget::UpdateData() { int axisX[m_SinPointX]; int axisY[m_SinPointX]; UpdateSinData(axisX,axisY); // SinData.h的接口函数 m_DataVectorX.clear(); m_DataVectorY.clear(); for(int n = 0 ; n 100) { int len = m_DataVectorX.length() -100; if( len < 0 ) len = 0-len; //m_FHRQwtPlot->setAxisScale(QwtPlot::xBottom,len,m_SinPointX,20); m_DataVectorX.erase(m_DataVectorX.begin(),m_DataVectorX.begin()+len); m_DataVectorY.erase(m_DataVectorY.begin(),m_DataVectorY.begin()+len); } m_FHRCurve->setSamples(m_DataVectorX,m_DataVectorY); m_FHRQwtPlot->replot(); m_UpdateFlag = 0; }

这样,这个Sin图像就完成了,和效果图一致。动态显示Sin曲线,并可调整振幅和周期。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有